package gepes.dao;

import gepes.exepcion.DAOExcepcion;
import gepes.modelo.Clase;
import gepes.modelo.Estudiante;
import gepes.modelo.Matricula;
import gepes.modelo.PagoEstudiante;
import gepes.modelo.TipoUsuario;
import gepes.util.Conexion;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;

public class MatriculaDAO extends Base {

	public PagoEstudiante insertaPago(PagoEstudiante vo) throws DAOExcepcion {
	
		String query = "insert into pagoestudiante(codmatricula,monto,fechapago,codmoneda,"
				+ "estado,fechareg,usuarioreg) "
				+ " values (?,?,now(),?,"
				+ "1,now(),?)";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = Conexion.ConectarDB();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, vo.getMatricula().getCodMatricula());
			stmt.setFloat(2, vo.getMonto());
			stmt.setInt(3, vo.getMoneda().getCodTipoMoneda());
			stmt.setString(4, vo.getUsuarioReg());
			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("Error insertar");
			}

			int id = 0;
			query = "select last_insert_id()";
			stmt = con.prepareStatement(query);
			rs = stmt.executeQuery();
			if (rs.next()) {
				id = rs.getInt(1);
			}
			vo.setCodPagoEstudiante(id);
			actualizapago(vo.getMatricula().getCodMatricula());
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return vo;
	}

	public boolean actualizapago(int id) throws DAOExcepcion {
		String query = "select costo from clase where codclase=?";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = Conexion.ConectarDB();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, id);

			rs = stmt.executeQuery();
			float costo = 0;
			if (rs.next()) {
				costo = rs.getFloat(1);
			}

			float montoPagado = this.montoPagado(id);
			if (montoPagado == costo) {
				query = "update matricula set pagado=true where codmatricula=?";
				stmt = con.prepareStatement(query);
				stmt.setInt(1, id);
				int i = stmt.executeUpdate();
				if (i != 1) {
					throw new SQLException("Error update");
				}

			}
			return true;
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
	}

	public boolean validapagos(int id, float monto) throws DAOExcepcion {
		String query = "select costo from clase inner join matricula on "
				+ "clase.codclase=matricula.codclase where codmatricula=?";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = Conexion.ConectarDB();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, id);

			rs = stmt.executeQuery();
			float costo = 0;
			if (rs.next()) {
				costo = rs.getFloat(1);
			}

			float montoPagado = this.montoPagado(id);
			if (montoPagado + monto > costo) {
				return false;

			}
			return true;
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
	}

	public float montoPagado(int id) throws DAOExcepcion {
		String query = "select sum(monto) "
				+ " from pagoestudiante where estado=1 and codmatricula=?";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = Conexion.ConectarDB();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, id);
			rs = stmt.executeQuery();
			if (rs.next()) {
				return rs.getFloat(1);
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return 0;
	}

	public int existe(int codclase, int codestudiante) throws DAOExcepcion {
		String query = "select count(0) "
				+ " from matricula m inner join usuario u on"
				+ " m.codestudiante=u.codusuario  inner join clase c "
				+ " on m.codclase=c.codclase where m.codclase=? and m.codestudiante=? "
				+ " and m.estado=1 order by m.codmatricula";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = Conexion.ConectarDB();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, codclase);
			stmt.setInt(2, codestudiante);

			rs = stmt.executeQuery();
			if (rs.next()) {
				return rs.getInt(1);
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return 0;
	}

	public Collection<PagoEstudiante> listarPagos(int codclase, int codestudiante)
			throws DAOExcepcion {
		String query = "select codpagoestudiante,monto,fechapago "
				+ " from pagoestudiante pg inner join matricula m on "
				+ " pg.codmatricula = m.codmatricula inner join usuario u on"
				+ " m.codestudiante=u.codusuario  inner join clase c "
				+ " on m.codclase=c.codclase where m.codclase=? and m.codestudiante=? "
				+ " and m.estado=1 order by m.codmatricula";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;

		Collection<PagoEstudiante> lista = new ArrayList<PagoEstudiante>();
		try {
			con = Conexion.ConectarDB();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, codclase);
			stmt.setInt(2, codestudiante);

			rs = stmt.executeQuery();
			while (rs.next()) {
				PagoEstudiante pe = new PagoEstudiante();
				pe.setCodPagoEstudiante(rs.getInt(1));
				pe.setMonto(rs.getFloat(2));
				pe.setFechaPago(rs.getDate(3));
				lista.add(pe);
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return lista;
	}

	public Matricula obtener(int id) throws DAOExcepcion {
		Matricula vo = new Matricula();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			String query = "select m.codmatricula,m.codclase, c.descripcion,"
					+ "m.codestudiante,u.apepat,u.apemat,u.nombre,u.pagado,m.estado "
					+ " from matricula m inner join usuario u on"
					+ " m.codestudiante=u.codusuario  inner join clase c "
					+ " on m.codclase=c.codclase where m.codmatricula=?";
			con = Conexion.ConectarDB();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, id);
			rs = stmt.executeQuery();
			if (rs.next()) {
				vo.setCodMatricula(rs.getInt(1));
				vo.setClase(new Clase(rs.getInt(2), rs.getString(3)));
				Estudiante es = new Estudiante();
				es.setCodUsuario(rs.getInt(4));
				es.setApePat(rs.getString(5));
				es.setApeMat(rs.getString(6));
				es.setNombres(rs.getString(7));
				vo.setEstudiante(es);
				vo.setPagado(rs.getBoolean(8));
				vo.setEstado(rs.getInt(9) == 1 ? true : false);
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return vo;
	}

	public Matricula insertar(Matricula tc) throws DAOExcepcion {
		String query = "insert into matricula(codclase,codestudiante,pagado,"
				+ "estado,fechareg,usuarioreg) "
				+ " values (?,?,false,1,now(),?)";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = Conexion.ConectarDB();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, tc.getClase().getCodClase());
			stmt.setInt(2, tc.getEstudiante().getCodUsuario());
			stmt.setString(3, tc.getUsuarioReg());

			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("Error insertar");
			}

			int id = 0;
			query = "select last_insert_id()";
			stmt = con.prepareStatement(query);
			rs = stmt.executeQuery();
			if (rs.next()) {
				id = rs.getInt(1);
			}
			tc.setCodMatricula(id);
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return tc;
	}

	public void anular(int id, boolean estado, String usuario) throws DAOExcepcion {
		String query = "update matricula set estado=? "
				+ (!estado ? " , fechaanul=now(), usuarioanul=?" : "")
				+ "WHERE codmatricula=?";
		Connection con = null;
		PreparedStatement stmt = null;
		try {
			con = Conexion.ConectarDB();
			stmt = con.prepareStatement(query);
			if (estado) {
				stmt.setInt(1, (estado ? 1 : 0));
				stmt.setInt(2, id);
			} else {
				stmt.setInt(1, (estado ? 1 : 0));
				stmt.setString(2, usuario);
				stmt.setInt(3, id);
			}
			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo "
						+ (estado ? "Activar" : "Anular"));
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
	}
}
